import re
# milestone 1 : Damavand
class Soft():
	def get_series_title(self):
		return self.series_title
	def get_samples(self):
		"""returns a list of samples"""
		return self.list_of_samples

	def get_values(self):
		"""returns a dics of samples that contain a dictionary of ids as keyword and their corresponding value as values """
		return self.dict_of_samples

	def get_table(self):
		"""returns a list of platform table"""
		return self.table

	def get_header(self):
		"""returns a list that corresponds to header of the platform table"""
		return self.table_header

	def name_to_ID(self, name):
		"""Changes the name of a gene symbol to corresponding probe ID"""
		list_of_dict_of_IDs = []
		iterator = 0
		for j in self.table_header[0]:
			if j is not None:
				match = re.search('Gene Symbol', j)
				if match:
					#print "an instance found!"
					list_of_dict_of_IDs.append({h[iterator]: h[0] for h in self.table}[name])
			iterator += 1
		return list_of_dict_of_IDs[0]

	#return { h[gene_symbol_column_no] : h[0] for h in self.table }[name]

	def ID_to_name(self, ID):
		"""Changes the ID  of a probe to corresponding gene symbol """
		iterator = 0
		gene_symbol_column_no = 0
		for j in self.table_header[0]:
			if j is not None:
				match = re.search('Gene Symbol', j)
				if match:
					gene_symbol_column_no = iterator

			iterator += 1
		return {h[0]: h[gene_symbol_column_no] for h in self.table}[ID]

	def get_genes(self):
		"""
		returns a lis of genes
		"""
		iterator = 0
		gene_symbol_column_no = 0
		try:
			for j in self.table_header[0]:
				if j is not None:
					match = re.search('Gene Symbol', j)
					if match:
						gene_symbol_column_no = iterator

				iterator += 1
		except:
			print("File Not supported")
		l = [x[gene_symbol_column_no] for x in self.table if x[gene_symbol_column_no] is not "" or " "]
		for i in l:
			if i == "":
				l.remove(i)
		return l

	def get_value_subsamples(self, name, list_of_samples):
		out = []
		for  i in range(len(list_of_samples)):
			out.append(float(self.dict_of_samples[list_of_samples[i]][self.name_to_ID(name)]))
		return out

	def name_value_all(self, name):
		out = []
		for  i in range(len(self.list_of_samples) - 1):
			out.append(float(self.dict_of_samples[self.list_of_samples[i]][self.name_to_ID(name)]))
		return out

	def __init__(self, name, verbose=True):
		"""This will create a soft object"""
		self.verbose = verbose
		self.table = []
		self.table_header = []
		self.list_of_samples = []
		self.dict_of_samples = {}
		self.my_file_name = name
		self.series_title = None
		self.series_ano = None
		self.platform_title = None
		self.platform_organism = None
		#self.__parse__()
	def read_file(self, file_name):
		if self.verbose: print "Opening the file..."
		for i in open(file_name, "r"):
			yield i.strip("\n")

	def find(self, pattern, i):
		match = re.search(pattern, i)
		if  match:
			my_string = match.group(1)
			if self.verbose: print my_string
			return my_string

	def parse2(self):
		# finding the sample list
		samples = 0
		table_process = False
		data = 1
		current_sample = ""
		Continue = True
		temp_list = dict()
		begin_capturing = False
		for i in self.read_file(self.my_file_name):
			if not Continue: break
			if self.series_title == None : self.series_title = self.find("!Series_title\s*\=\s*(.+)", i)
			if self.series_ano == None :self.series_ano = self.find("!Series_geo_accession\s*\=\s*(\w+)", i)
			if self.platform_title == None :self.platform_title = self.find("!Platform_title\s*\=\s*(.+)", i)
			if self.platform_organism == None :self.platform_organism = self.find("!Platform_organism\s*\=\s*(.+)", i)
			sample = re.search("!Series_sample_id\s\=\s(\w+)", i)
			if sample:
				samples += 1
				self.list_of_samples.append(sample.group(1))

			# constructing data table

			table_end_match = re.search("!platform_table_end", i)
			if table_end_match:
				table_process = False

			if table_process:
				if data == 1:
					#Creating header for table
					self.table_header.append(i.split("\t"))
				else:
					self.table.append(i.split("\t"))
				data += 1
			# data for each sample
			if re.search("\!sample_table_end", i):
				new_sample = {current_sample: temp_list}
				self.dict_of_samples.update(new_sample)
				if self.verbose: print "%s Updated!" % current_sample
				yield current_sample
				temp_list = {}
				begin_capturing = False

			table_begin_match = re.search("!platform_table_begin", i)
			if table_begin_match:
				table_process = True


			# constructing values for each sample
			if begin_capturing:
				temp_list.update({i.split("\t")[0]: i.split("\t")[1]})

			match = re.search("\^SAMPLE\s=\s(\w+)", i)
			if match:
				if self.verbose: print self.series_title; print "sample %s found!" % match.group(1)
				current_sample = match.group(1)
			if re.search("\!sample_table_begin", i):
				begin_capturing = True

				pass
	def __parse__(self):
		# finding the sample list
		samples = 0
		table_process = False
		data = 1
		current_sample = ""
		Continue = True
		temp_list = dict()
		begin_capturing = False
		for i in self.read_file(self.my_file_name):
			if i is None:break
			if not Continue: break
			self.series_title = self.find("!Series_title\s*\=\s*(.+)", i)
			self.series_ano = self.find("!Series_geo_accession\s*\=\s*(\w+)", i)
			self.platform_title = self.find("!Platform_title\s*\=\s*(.+)", i)
			self.platform_organism = self.find("!Platform_organism\s*\=\s*(.+)", i)
			sample = re.search("!Series_sample_id\s\=\s(\w+)", i)
			if sample:
				samples += 1
				self.list_of_samples.append(sample.group(1))

			# constructing data table

			table_end_match = re.search("!platform_table_end", i)
			if table_end_match:
				table_process = False

			if table_process:
				if data == 1:
					#Creating header for table
					self.table_header.append(i.split("\t"))
				else:
					self.table.append(i.split("\t"))
				data += 1
			# data for each sample
			if re.search("\!sample_table_end", i):
				new_sample = {current_sample: temp_list}
				self.dict_of_samples.update(new_sample)
				if self.verbose: print "%s Updated!" % current_sample
				temp_list = {}
				begin_capturing = False

			table_begin_match = re.search("!platform_table_begin", i)
			if table_begin_match:
				table_process = True


			# constructing values for each sample
			if begin_capturing:
				temp_list.update({i.split("\t")[0]: i.split("\t")[1]})

			match = re.search("\^SAMPLE\s=\s(\w+)", i)
			if match:
				if self.verbose: print "sample %s found!" % match.group(1)
				current_sample = match.group(1)
			if re.search("\!sample_table_begin", i):
				begin_capturing = True

				pass

import matplotlib.pyplot as pp
import numpy as np

class Graph:
	"""
	Creates graph object to plot microarray data
	"""

	def __init__(self, parser):
		"""
		parser: an instance of the parser object
		"""
		self.parser = parser

		pass

	def plot(self, list_of_genes, list_of_samples):
		"""
			list_of_genes: list of gene names
			list_of_samples: list of sample names
		"""

		data = np.zeros((len(list_of_genes), len(list_of_samples)))
		iterator = 0
		for i in list_of_genes:
			one_gene_data = self.parser.get_value_subsamples(i, list_of_samples)
			data[iterator] = one_gene_data

			iterator += 1

		#data.shape = ( len(list_of_genes), len (self.parser.get_value_subsamples(i,list_of_samples)))

		f, (a1, a2) = pp.subplots(2, 1)
		a1.imshow(data, cmap=pp.get_cmap("cool"), interpolation="nearest")
		a1.xaxis.set_visible(False)
		a1.yaxis.set_visible(False)

		iterator = 0
		for j in data:
			a2.plot(j, label=list_of_genes[iterator])
			iterator += 1
		a2.legend(list_of_genes)
		pp.show()

	def get_plot(self, list_of_genes, list_of_samples):
		"""
			list_of_genes: list of gene names
			list_of_samples: list of sample names
		"""

		data = np.zeros((len(list_of_genes), len(list_of_samples)))
		iterator = 0
		for i in list_of_genes:
			one_gene_data = self.parser.get_value_subsamples(i, list_of_samples)
			data[iterator] = one_gene_data

			iterator += 1

		#data.shape = ( len(list_of_genes), len (self.parser.get_value_subsamples(i,list_of_samples)))

		#f = pp.figure()
		#f.add_subplot(211)

		f, (a1, a2) = pp.subplots(2, 1)
		#a1.imshow(data, cmap=pp.get_cmap("cool"), interpolation="nearest")
		a1.matshow(data, cmap=pp.get_cmap("cool"), interpolation="nearest")
		a1.set_xticklabels([""] + list_of_samples)
		a1.set_yticklabels([""] + list_of_genes)
		labels = a1.get_xticklabels()
		for label in labels:
			label.set_rotation(90)

		#a1.xaxis.set_visible(False)
		#a1.yaxis.set_visible(False)

		iterator = 0
		for j in data:
			a2.plot(j, label=list_of_genes[iterator])
			iterator += 1
		a2.legend(list_of_genes)
		a2.set_xticklabels(list_of_samples)
		return f

